package handler

import (
	"context"
	"fmt"
	"gitee.com/worklz/dtm-tcc-demo/server-payment/domain/dto"
	paymentpb "gitee.com/worklz/dtm-tcc-demo/server-payment/proto/payment"
	"github.com/google/uuid"
	"sync"
	"time"
)

type PaymentHandler struct {
	paymentpb.UnimplementedPaymentServiceServer                         // 关键：嵌入默认实现
	accounts                                    map[string]*dto.Account // 账户存储
	payments                                    map[string]*dto.Payment // 支付记录
	txDatas                                     map[string]*TxData      // 事务数据记录 tx_id -> data
	mu                                          sync.RWMutex
}

// 事务数据
type TxData struct {
	TxId      string // 事务id
	PaymentId string // 支付id
	Status    string // 事务状态
}

var _ paymentpb.PaymentServiceServer = (*PaymentHandler)(nil)

func NewPaymentHandler() *PaymentHandler {
	return &PaymentHandler{
		accounts: make(map[string]*dto.Account),
		payments: make(map[string]*dto.Payment),
		txDatas:  make(map[string]*TxData),
	}
}

// 初始化用户账户（实际项目中应该从数据库加载）
func (h *PaymentHandler) initAccount(userId string) {
	if _, exists := h.accounts[userId]; !exists {
		h.accounts[userId] = &dto.Account{
			UserId:  userId,
			Balance: 10000, // 默认初始余额
			Frozen:  0,
		}
	}
}

// TryPayment 尝试支付-Try阶段
func (h *PaymentHandler) TryPayment(ctx context.Context, req *paymentpb.TccPaymentRequest) (res *paymentpb.TccPaymentResponse, err error) {
	h.mu.Lock()
	defer h.mu.Unlock()
	//err = status.Errorf(500, "测试未知支付异常1")
	//res = &paymentpb.TccPaymentResponse{
	//	Success: false,
	//	Message: "测试未知支付异常2",
	//}
	//return
	// 幂等性检查
	if txData, exists := h.txDatas[req.TxId]; exists {
		if txData.Status == "try" {
			// 查找该事务的支付记录
			for _, payment := range h.payments {
				if payment.UserId == req.UserId && payment.OrderId == req.OrderId &&
					payment.Amount == req.Amount && payment.Status == "PENDING" {
					res = &paymentpb.TccPaymentResponse{
						Success:   true,
						PaymentId: payment.PaymentId,
					}
					return
				}
			}
		}
		res = &paymentpb.TccPaymentResponse{
			Success: false,
			Message: fmt.Sprintf("事务状态错误: %s", txData.Status),
		}
		return
	}

	// 初始化用户账户
	h.initAccount(req.UserId)

	// 检查余额是否充足
	account := h.accounts[req.UserId]
	if account.Balance < req.Amount {
		res = &paymentpb.TccPaymentResponse{
			Success: false,
			Message: "余额不足",
		}
		return
	}

	// 扣减可用余额，增加冻结金额
	account.Balance -= req.Amount
	account.Frozen += req.Amount
	h.accounts[req.UserId] = account

	// 创建支付记录
	paymentId := uuid.New().String()
	payment := &dto.Payment{
		PaymentId: paymentId,
		UserId:    req.UserId,
		OrderId:   req.OrderId,
		Amount:    req.Amount,
		Status:    "PENDING",
		CreatedAt: time.Now(),
	}
	h.payments[paymentId] = payment
	h.txDatas[req.TxId] = &TxData{
		PaymentId: paymentId,
		Status:    "try",
		TxId:      req.TxId,
	}

	res = &paymentpb.TccPaymentResponse{
		Success:   true,
		PaymentId: paymentId,
	}
	return
}

// ConfirmPayment 确认支付-Confirm阶段
func (h *PaymentHandler) ConfirmPayment(ctx context.Context, req *paymentpb.TccPaymentRequest) (res *paymentpb.TccPaymentResponse, err error) {
	h.mu.Lock()
	defer h.mu.Unlock()

	// 幂等性检查
	txData, exists := h.txDatas[req.TxId]
	if exists {
		if txData.Status == "confirm" {
			res = &paymentpb.TccPaymentResponse{Success: true}
			return
		}
		if txData.Status != "try" {
			res = &paymentpb.TccPaymentResponse{
				Success: false,
				Message: fmt.Sprintf("事务状态错误: %s", txData.Status),
			}
			return
		}
	} else {
		// 空回滚处理
		res = &paymentpb.TccPaymentResponse{Success: true}
		return
	}

	// 扣减冻结金额（完成实际支付）
	payment, exists := h.payments[txData.PaymentId]
	if !exists {
		res = &paymentpb.TccPaymentResponse{
			Success: false,
			Message: "支付记录不存在",
		}
		return
	}

	account, exists := h.accounts[payment.UserId]
	if !exists {
		res = &paymentpb.TccPaymentResponse{
			Success: false,
			Message: "账户不存在",
		}
		return
	}

	account.Frozen -= payment.Amount
	h.accounts[payment.UserId] = account

	// 更新支付状态
	payment.Status = "CONFIRMED"
	h.payments[txData.PaymentId] = payment
	txData.Status = "confirm"
	h.txDatas[req.TxId] = txData

	res = &paymentpb.TccPaymentResponse{Success: true}
	return
}

// CancelPayment 取消支付-Cancel阶段
func (h *PaymentHandler) CancelPayment(ctx context.Context, req *paymentpb.TccPaymentRequest) (res *paymentpb.TccPaymentResponse, err error) {
	h.mu.Lock()
	defer h.mu.Unlock()

	// 幂等性检查
	txData, exists := h.txDatas[req.TxId]
	if exists {
		if txData.Status == "cancel" {
			res = &paymentpb.TccPaymentResponse{Success: true}
			return
		}
		if txData.Status != "try" {
			res = &paymentpb.TccPaymentResponse{
				Success: false,
				Message: fmt.Sprintf("事务状态错误: %s", txData.Status),
			}
			return
		}
	} else {
		// 空回滚处理
		res = &paymentpb.TccPaymentResponse{Success: true}
		return
	}

	// 解冻金额，恢复可用余额
	payment, exists := h.payments[txData.PaymentId]
	if !exists {
		res = &paymentpb.TccPaymentResponse{
			Success: false,
			Message: "支付记录不存在",
		}
		return
	}

	account, exists := h.accounts[payment.UserId]
	if !exists {
		res = &paymentpb.TccPaymentResponse{
			Success: false,
			Message: "账户不存在",
		}
		return
	}

	account.Frozen -= payment.Amount
	account.Balance += payment.Amount
	h.accounts[payment.UserId] = account

	// 更新支付状态
	payment.Status = "CANCELED"
	h.payments[txData.PaymentId] = payment
	txData.Status = "cancel"
	h.txDatas[req.TxId] = txData

	res = &paymentpb.TccPaymentResponse{Success: true}
	return
}
